home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / SRC1229A.ARJ / FTPSUBR.C < prev    next >
C/C++ Source or Header  |  1991-12-16  |  4KB  |  186 lines

  1. /* Routines common to both the FTP client and server
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "mbuf.h"
  7. #include "socket.h"
  8. #include "proc.h"
  9. #include "ftp.h"
  10.  
  11. /* Send a file (opened by caller) on a network socket.
  12.  * Normal return: count of bytes sent
  13.  * Error return: -1
  14.  */
  15. long
  16. sendfile(fp,s,mode,hash)
  17. FILE *fp;    /* File to be sent */
  18. int s;        /* Socket to be sent on */
  19. int mode;    /* Transfer mode */
  20. int hash;    /* Print hash marks every BLKSIZE bytes */
  21. {
  22.     register struct mbuf *bp;
  23.     int c,oldf;
  24.     long total = 0;
  25.     long hmark = 0;
  26.  
  27.     switch(mode){
  28.     default:
  29.     case LOGICAL_TYPE:
  30.     case IMAGE_TYPE:
  31.         sockmode(s,SOCK_BINARY);
  32.         for(;;){
  33.             bp = ambufw(BLKSIZE);
  34.             if((bp->cnt = fread(bp->data,1,BLKSIZE,fp)) == 0){
  35.                 free_p(bp);
  36.                 break;
  37.             }
  38.             total += bp->cnt;
  39.             if(send_mbuf(s,bp,0,NULLCHAR,0) == -1){
  40.                 total = -1;
  41.                 break;
  42.             }
  43.             while(hash && total >= hmark+1000){
  44.                 tputc('#');
  45.                 hmark += 1000;
  46.             }
  47.         }
  48.         break;
  49.     case ASCII_TYPE:
  50.         oldf = setflush(s,-1);
  51.         /* Let the newline mapping code in usputc() do the work */
  52.         sockmode(s,SOCK_ASCII);
  53.         while((c = getc(fp)) != EOF){
  54. #if !defined(UNIX) && !defined(__TURBOC__)
  55.             if(c == '\r'){
  56.                 /* Needed only if the OS uses a CR/LF
  57.                  * convention and getc doesn't do
  58.                  * an automatic translation
  59.                  */
  60.                 continue;
  61.             }
  62. #endif
  63.             if(usputc(s,(char)c) == -1){
  64.                 total = -1;
  65.                 break;
  66.             }
  67.             total++;
  68.             while(hash && total >= hmark+1000){
  69.                 tputc('#');
  70.                 hmark += 1000;
  71.             }
  72.         }
  73.         usflush(s);
  74.         setflush(s,oldf);        
  75.         break;
  76.     }
  77.     if(hash)
  78.         tputc('\n');
  79.     return total;
  80. }
  81. /* Receive a file (opened by caller) from a network socket.
  82.  * Normal return: count of bytes received
  83.  * Error return: -1
  84.  */
  85. long
  86. recvfile(fp,s,mode,hash)
  87. FILE *fp;
  88. int s;
  89. int mode;
  90. int hash;
  91. {
  92.     int cnt,c;
  93.     struct mbuf *bp;
  94.     long total = 0;
  95.     long hmark = 0;
  96.  
  97.     switch(mode){
  98.     default:
  99.     case LOGICAL_TYPE:
  100.     case IMAGE_TYPE:
  101.         sockmode(s,SOCK_BINARY);
  102.         while((cnt = recv_mbuf(s,&bp,0,NULLCHAR,0)) != 0){
  103.             if(cnt == -1){
  104.                 total = -1;
  105.                 break;
  106.             }
  107.             total += cnt;
  108.             while(hash && total >= hmark+1000){
  109.                 tputc('#');
  110.                 hmark += 1000;
  111.             }
  112.             if(fp != NULLFILE){
  113.                 if(write_p(fp,bp) == -1){
  114.                     free_p(bp);
  115.                     total = -1;
  116.                     break;
  117.                 }
  118.                 free_p(bp);
  119.             } else {
  120.                 send_mbuf(Curproc->output, bp, 0, NULLCHAR, 0);
  121.             }
  122.         }
  123.         break;
  124.     case ASCII_TYPE:
  125.         sockmode(s,SOCK_ASCII);
  126.         while((c = recvchar(s)) != EOF){
  127.             if(fp != NULLFILE){
  128. #if !defined(UNIX) && !defined(__TURBOC__) && !defined(AMIGA)
  129.                 if(c == '\n'){
  130.                     /* Needed only if the OS uses a CR/LF
  131.                      * convention and putc doesn't do
  132.                      * an automatic translation
  133.                      */
  134.                     putc('\r',fp);
  135.                 }
  136. #endif
  137.                 if(putc(c,fp) == EOF){
  138.                     total = -1;
  139.                     break;
  140.                 }
  141.             } else {
  142.                 tputc((char)c);
  143.             }
  144.             total++;
  145.             while(hash && total >= hmark+1000){
  146.                 tputc('#');
  147.                 hmark += 1000;
  148.             }
  149.         }
  150.         /* Detect an abnormal close */
  151.         if(socklen(s,0) == -1)
  152.             total = -1;
  153.         break;
  154.     }
  155.     if(hash)
  156.         tputc('\n');
  157.     return total;
  158. }
  159. /* Determine if a file appears to be binary (i.e., non-text).
  160.  * Return 1 if binary, 0 if ascii text after rewinding the file pointer.
  161.  *
  162.  * Used by FTP to warn users when transferring a binary file in text mode.
  163.  */
  164. int
  165. isbinary(fp)
  166. FILE *fp;
  167. {
  168.     int c,i;
  169.     int rval;
  170.  
  171.     rval = 0;
  172.     for(i=0;i<512;i++){
  173.         if((c = getc(fp)) == EOF)
  174.             break;
  175.         if(c & 0x80){
  176.             /* High bit is set, probably not text */
  177.             rval = 1;
  178.             break;
  179.         }
  180.     }
  181.     /* Assume it was at beginning */
  182.     fseek(fp,0L,SEEK_SET);
  183.     return rval;
  184. }
  185.  
  186.